package com.yonyou.pmclouds.basecom.dao;

import com.yonyou.pmclouds.basecom.dao.impl.mybatis.BaseSQLProvider;
import com.yonyou.pmclouds.basecom.dao.query.CustomQueryParam;
import com.yonyou.pmclouds.basecom.dao.query.Sort;
import com.yonyou.pmclouds.basecom.entity.Entity;
import org.apache.ibatis.annotations.*;

import java.util.List;

/**
 * @author zm
 */
public interface BaseMapper<T extends Entity> {

    String PARAM_VO = "vo";
    String PARAM_FIELDS = "fields";
    String PARAM_ORIG_CHANGE_FLAG = "origChangeFlag";
    String PARAM_PKS = "pks";

    /**
     * 默认获取单表所有数据。可通过mapper.xml覆盖默认sql。
     *
     * @deprecated 除非数量可控，否则不要禁用
     */
    @Deprecated
    @SelectProvider(type = BaseSQLProvider.class, method = "getAll")
    @ResultMap("getMap")
    List<T> getAll();

    @SelectProvider(type = BaseSQLProvider.class, method = "getById")
    @ResultMap("getMap")
    T getById(Object id);

    /**
     * 该方法可能存在sql注入风险，严禁使用
     */
    @Deprecated
    @SelectProvider(type = BaseSQLProvider.class, method = "getByBillIds")
    @ResultMap("getMap")
    T[] getByBillIds(@Param("ids") Object ids);

    @SelectProvider(type = BaseSQLProvider.class, method = "getByIdWithOutDr")
    @ResultMap("getMap")
    T getByIdWithOutDr(Object id);

    @SelectProvider(type = BaseSQLProvider.class, method = "get")
    @ResultMap("getMap")
    T getOne(@Param("findParams") T findParams);

    /**
     * 见{@link com.yonyou.pmclouds.basecom.dao.BaseMapper#get}
     */
    @SelectProvider(type = BaseSQLProvider.class, method = "countGet")
    int countGet(@Param("findParams") T findParams);

    /**
     * 根据当前表中的属性精确查询。模糊查询可用{@link com.yonyou.pmclouds.basecom.dao.BaseMapper#find}，复杂查询可用{@link com.yonyou.pmclouds.basecom.dao.BaseMapper#query}
     */
    @SelectProvider(type = BaseSQLProvider.class, method = "get")
    @ResultMap("getMap")
    List<T> get(@Param("findParams") T findParams);

    @SelectProvider(type = BaseSQLProvider.class, method = "getIdsByPrj")
    @ResultType(String.class)
    String[] getIdsByPrj(@Param("pkProject") String pkProject);

    @SelectProvider(type = BaseSQLProvider.class, method = "get")
    @ResultMap("getMap")
    List<T> getPage(@Param("findParams") T findParams, @Param("sortList") List<Sort> sortList, @Param("start") Integer start, @Param("limit") Integer limit);

    /**
     * 见{@link com.yonyou.pmclouds.basecom.dao.BaseMapper#find}
     *
     * @return
     */
    @SelectProvider(type = BaseSQLProvider.class, method = "countFind")
    int countFind(@Param("findParams") T findParams);

    /**
     * 根据当前表中的属性模糊查询。精确查询可用{@link com.yonyou.pmclouds.basecom.dao.BaseMapper#get}，复杂查询可用{@link com.yonyou.pmclouds.basecom.dao.BaseMapper#query}
     *
     * @return
     */
    @SelectProvider(type = BaseSQLProvider.class, method = "find")
    @ResultMap("getMap")
    List<T> find(@Param("findParams") T findParams);

    @SelectProvider(type = BaseSQLProvider.class, method = "find")
    @ResultMap("getMap")
    List<T> findPage(@Param("findParams") T findParams, @Param("sortList") List<Sort> sortList, @Param("start") Integer start, @Param("limit") Integer limit);

    /**
     * 见{@link com.yonyou.pmclouds.basecom.dao.BaseMapper#query}
     *
     * @return
     */
    @SelectProvider(type = BaseSQLProvider.class, method = "countQuery")
    int countQuery(@Param("queryParams") List<CustomQueryParam> customQueryParams);

    /**
     * 复杂查询。另见{@link com.yonyou.pmclouds.basecom.dao.BaseMapper#get}、{@link com.yonyou.pmclouds.basecom.dao.BaseMapper#find}。例：
     * <pre><code>
     * QueryParamBuilder queryParamBuilder = QueryParamBuilder.newBuilder();
     * queryParamBuilder.addWithValueQueryParam("city", "=", city);
     * queryParamBuilder.addWithValueQueryParam("name", "LIKE", "%" + name + "%");
     * queryParamBuilder.addWithValueQueryParam("date", ">", time1);
     * queryParamBuilder.addWithValueQueryParam("date", "<=", time2);
     * List<CustomQueryParam> queryParams = queryParamBuilder.build();
     * </code></pre>
     *
     * @return
     */
    @SelectProvider(type = BaseSQLProvider.class, method = "query")
    @ResultMap("getMap")
    List<T> query(@Param("queryParams") List<CustomQueryParam> customQueryParams, @Param("sortList") List<Sort> sortList);

    @SelectProvider(type = BaseSQLProvider.class, method = "query")
    @ResultMap("getMap")
    List<T> queryPage(@Param("queryParams") List<CustomQueryParam> customQueryParams, @Param("sortList") List<Sort> sortList, @Param("start") Integer start, @Param("limit") Integer limit);

    @InsertProvider(type = BaseSQLProvider.class, method = "insert")
    int insert(T t);
    
    @InsertProvider(type = BaseSQLProvider.class, method = "batchInsert")
    int batchInsert(@Param("vos") List<T> t);
    
    @DeleteProvider(type = BaseSQLProvider.class, method = "delete")
    int delete(Object id);

    @UpdateProvider(type = BaseSQLProvider.class, method = "update")
    int update(T t);

    /**
     * 更新vo，只更新制定字段,同时更新changeFlag
     */
    @UpdateProvider(type = BaseSQLProvider.class, method = "updateFields")
    int updateFields(@Param(PARAM_VO) T t, @Param(PARAM_FIELDS) String[] fields);

    /**
     * 更新vo，只更新制定字段,不更新changFlag
     */
    @UpdateProvider(type = BaseSQLProvider.class, method = "updateFieldsWithoutFlag")
    int updateFieldsWithoutFlag(@Param(PARAM_VO) T t, @Param(PARAM_FIELDS) String[] fields);

    /**
     * 更新vo，只更新制定字段,同时更新changeFlag，但是changeflag与origChangeFlag不同，不更新
     */
    @UpdateProvider(type = BaseSQLProvider.class, method = "updateFieldsWithFlagCond")
    int updateFieldsWithFlagCond(@Param(PARAM_VO) T t, @Param(PARAM_FIELDS) String[] fields,
                                 @Param(PARAM_ORIG_CHANGE_FLAG) String origChangeFlag);

    /**
     *  根据主键批量更新,试用于更改字段内容一样  例如批删
     */
    @UpdateProvider(type = BaseSQLProvider.class, method = "batchUpdateFieldsByPks")
    int batchUpdateFieldsByPks(@Param(PARAM_VO) T t, @Param(PARAM_FIELDS) String[] fields, @Param(PARAM_PKS) String[] pks);
}